package com.alibaba.citrus.ots.sales.plan.facade.service.statistics;

import com.alibaba.acm.shaded.com.google.common.collect.Sets;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.lock.RedisLock;
import com.alibaba.citrus.ots.common.log.CommonErrorCode;
import com.alibaba.citrus.ots.sales.plan.api.statistics.SalesPlanStatService;
import com.alibaba.citrus.ots.sales.plan.contants.SalesPlanLockKey;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.MonthContractAndRollingCountResponse;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QueryContractByCustomerDimensionRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.citrus.ots.sales.plan.facade.service.statistics.stat.ConformityStatService;
import com.alibaba.citrus.ots.sales.plan.facade.service.statistics.stat.customer.CustomerStatService;
import com.alibaba.citrus.ots.sales.plan.facade.service.statistics.stat.model.SalesPlanStatRequest;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractDataSourceEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractStatDimensionEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.StatPoolTypeEnum;
import com.alibaba.citrus.ots.sales.plan.repository.ContractRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanCustomerStatRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanLineRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.ots.sales.plan.repository.request.StatCategoryQueryRequest;
import com.alibaba.citrus.ots.sales.plan.repository.request.StatOrganizationQueryRequest;
import com.alibaba.citrus.ots.sales.plan.repository.request.StatScItemQueryRequest;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.bcots.sales_plan.planscitem.dto.PlanCategoryStatCountRequest;
import com.epoch.app.bcots.sales_plan.planscitem.dto.PlanCategoryStatCountResponse;
import com.epoch.app.bcots.sales_plan.planscitem.dto.PlanOrganizationStatCountRequest;
import com.epoch.app.bcots.sales_plan.planscitem.dto.PlanOrganizationStatCountResponse;
import com.epoch.app.bcots.sales_plan.planscitem.service.PlanScItemService;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatByBusinessUnitCountRequest;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatByBusinessUnitCountResponse;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatByManageEmployeeCountRequest;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatByManageEmployeeCountResponse;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesChannelCountRequest;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesChannelCountResponse;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesDepartmentCountRequest;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesDepartmentCountResponse;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesOrganizationCountRequest;
import com.epoch.app.bcots.sales_plan.salesplandetail.dto.PlanScItemStatBySalesOrganizationCountResponse;
import com.epoch.app.bcots.sales_plan.salesplandetail.service.SalesPlanDetailService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author luyi
 * @date 2021/9/25 10:12 下午
 */
@Service
public class SalesPlanStatServiceImpl implements SalesPlanStatService {

    private static final Log log = Log.getLogger(SalesPlanStatServiceImpl.class);
    @Resource
    private SalesPlanDetailService salesPlanDetailService;
    @Resource
    private PlanScItemService planScItemService;
    @Resource
    private SalesPlanRepository salesPlanRepository;
    @Resource
    private ContractRepository contractRepository;
    @Resource
    private SalesPlanLineRepository salesPlanLineRepository;
    @Resource
    private SalesPlanCustomerStatRepository salesPlanCustomerStatRepository;
    @Resource
    private SalesPlanScItemStatRepository salesPlanScItemStatRepository;
    /**
     * 客户地址page_size
     */
    private static final Integer CUSTOMER_ADDRESS_PAGE_SIZE = 500;

    @Resource(name = "salesPlanTaskExecutor")
    private ThreadPoolTaskExecutor salesPlanTaskExecutor;

    /**
     * 计划明细汇总
     * 计划状态 待锁定 待回复
     * 触发汇总
     *
     * @param planId 计划id
     * @return
     */
    @FacadeInvoker
    @Override
    public Result<Boolean> planCollect(String planId) {
        QuerySalesPlanRequest request = new QuerySalesPlanRequest();
        request.setId(planId);
        SalesPlanSDO salesPlanSDO = salesPlanRepository.load(request);
        if (salesPlanSDO == null) {
            throw new FacadeException("OTS-02-002-00-16-001");
        }
        if (SalesPlanStatusEnum.CANCEL.getCode().equals(salesPlanSDO.getStatus())) {
            //计划已经取消
            throw new FacadeException("OTS-02-002-00-16-003");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(Long.parseLong(salesPlanSDO.getPlanTime())));
        String year = Objects.toString(calendar.get(Calendar.YEAR), null);
        String month = Objects.toString(calendar.get(Calendar.MONTH) + 1, null);

        try (RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(), SalesPlanLockKey.getPlanStatLockKey(planId))) {
            boolean locked = lock.lock();
            if (!locked) {
                log.error("SalesPlanStatServiceImpl#planCollect.getLock.fail planId=" + planId);
                return Result.fail("OTS-02-006-00-16-005", "该计划正在汇总，请稍后重试");
            }
            log.info("SalesPlanStatServiceImpl#planCollect.start planId=" + planId);
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            deleteStatData(planId);

            SalesPlanStatRequest statRequest = new SalesPlanStatRequest(salesPlanSDO, year, month);
            final CountDownLatch latch = new CountDownLatch(2);
            salesPlanTaskExecutor.execute(new CustomerStatService(statRequest, latch));
            salesPlanTaskExecutor.execute(new ConformityStatService(statRequest, latch));
            latch.await(35,TimeUnit.SECONDS);
            stopWatch.stop();

            log.info("SalesPlanStatServiceImpl#planCollect.end planId=" + planId + " elapsed time:" + stopWatch.getTotalTimeMillis() + "ms");

//            long startNanoTime = System.nanoTime();
//            CompletableFuture<Void> customerFuture = CompletableFuture.runAsync(() -> {
//                planCustomerCollect(salesPlanSDO, year, month);
//            }, salesPlanTaskExecutor);
//            CompletableFuture<Void> scItemFuture = CompletableFuture.runAsync(() -> {
//                planScItemCollect(salesPlanSDO, year, month);
//            }, salesPlanTaskExecutor);
//            CompletableFuture<Void> voidCompletableFuture = customerFuture.runAfterBoth(scItemFuture, () -> {
//                long escapedMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
//                log.info("planId=" + planId + " collect end.elapsed time=" + escapedMillis);
//            });
//            voidCompletableFuture.join();
        } catch (Exception e) {
            log.error("SalesPlanStatServiceImpl#planCollect_fail  ", e);
            return Result.fail(CommonErrorCode.SYSTEM_ERROR, "系统开小差了");
        }
        return Result.success(true);
    }

    @FacadeInvoker
    @Override
    public Result<Boolean> deleteStatData(String planId) {
        Boolean deletePlanCustomer = salesPlanCustomerStatRepository.deletePlanCustomerByPlanId(planId);
        Boolean deletePlanScItem = salesPlanScItemStatRepository.deletePlanScItemByPlanId(planId);
        return Result.success(deletePlanCustomer && deletePlanScItem);
    }

//    /**
//     * 客户维度汇总
//     *
//     * @param salesPlan
//     */
//    public void planCustomerCollect(SalesPlanSDO salesPlan, String year, String month) {
//        //获取有多少客户地址
//        log.info("SalesPlanStatServiceImpl.planCustomerCollect.start");
//        Integer addressCount = salesPlanLineRepository.queryPlanCustomerCount(salesPlan.getId().toString());
//        if (addressCount == null || addressCount <= 0) {
//            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
//            return;
//        }
//        int totalPage = (addressCount + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
//        for (int i = 1; i <= totalPage; i++) {
//            StatCustomerQueryRequest statQueryRequest = new StatCustomerQueryRequest();
//            statQueryRequest.setPlanId(salesPlan.getId().toString());
//            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
//            statQueryRequest.setPage(i);
//            List<SalesPlanStatCustomerSDO> salesPlanStatCustomerList = salesPlanLineRepository.queryStatPlanCustomerList(statQueryRequest);
//            if (CollectionUtils.isEmpty(salesPlanStatCustomerList)) {
//                log.warn("SalesPlanStatServiceImpl.planCustomerCollect.salesPlanStatCustomerList nothingness");
//                break;
//            }
//            //批量查询客户地址合同量，合同金额
//            List<String> customerAddressList = salesPlanStatCustomerList.stream().map(SalesPlanStatCustomerSDO::getCustomerAddress).collect(Collectors.toList());
//            List<String> customerAddressIdList = salesPlanStatCustomerList.stream().map(SalesPlanStatCustomerSDO::getCustomerAddressId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
//
//            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
//            queryContractRequest.setType(ContractStatDimensionEnum.CUSTOMER.getCode());
//            queryContractRequest.setCustomerAddresses(customerAddressList);
//            if (CollectionUtils.isNotEmpty(customerAddressIdList)){
//                queryContractRequest.setCustomerAddressesIds(customerAddressIdList);
//            }
//            queryContractRequest.setContractYear(year);
//            queryContractRequest.setPlanMonth(month);
//            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
//            List<MonthContractAndRollingCountResponse> monthContractAndRollingCountResponses = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
//            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
//            if (CollectionUtils.isNotEmpty(monthContractAndRollingCountResponses)) {
//                collect = monthContractAndRollingCountResponses.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getCustomerAddress, a -> a, (a, b) -> a));
//            }
//            //计算合同满意度 计划状态不同 计算满意度方式不同
//            for (SalesPlanStatCustomerSDO planStatCustomer : salesPlanStatCustomerList) {
//                //查合同量补充
//                MonthContractAndRollingCountResponse monthContract = collect.get(planStatCustomer.getCustomerAddress());
//                setStatContractInfo(planStatCustomer, monthContract);
//                calculateSatisfaction(salesPlan.getStatus(), planStatCustomer);
//            }
//            salesPlanCustomerStatRepository.batchCreatePlanCustomer(salesPlanStatCustomerList);
//        }
//        log.info("SalesPlanStatServiceImpl.planCustomerCollect.end");
//    }


    /**
     * 多维度汇总
     *
     * @param salesPlan
     */
    public void planScItemCollect(SalesPlanSDO salesPlan, String year, String month) {
        log.info("SalesPlanStatServiceImpl.planScItemCollect.start");
        //以下 货品维度汇总可以多线程同步进行
        statEmployeeScItem(salesPlan, year, month);
        statDepartmentScItem(salesPlan, year, month);
        statChannelScItem(salesPlan, year, month);
        statOrganizationScItem(salesPlan, year, month);
        statBusinessUnitScItem(salesPlan, year, month);

        CompletableFuture<Void> orgFuture = CompletableFuture.runAsync(() -> {
            //组织维度汇总 （货品结束后，可以开始）
            statEmployee(salesPlan, year, month);
            statDepartment(salesPlan, year, month);
            statChannel(salesPlan, year, month);
            statOrganization(salesPlan, year, month);
            statBusinessUnit(salesPlan, year, month);
        }, salesPlanTaskExecutor);

        CompletableFuture<Void> categoryFuture = CompletableFuture.runAsync(() -> {
            //类目维度  （货品结束后，可以开始）
            statEmployeeCategory(salesPlan, year, month);
            statDepartmentCategory(salesPlan, year, month);
            statChannelCategory(salesPlan, year, month);
            statOrganizationCategory(salesPlan, year, month);
            statBusinessUnitCategory(salesPlan, year, month);
        }, salesPlanTaskExecutor);
        CompletableFuture<Void> voidCompletableFuture = orgFuture.runAfterBoth(categoryFuture, () -> {

        });
        voidCompletableFuture.join();
        log.info("SalesPlanStatServiceImpl.planScItemCollect.end");
    }

    /**
     * 类目维度
     * 销售组织类目汇总
     *
     * @param salesPlan
     */
    private void statBusinessUnitCategory(SalesPlanSDO salesPlan, String year, String month) {

        PlanCategoryStatCountRequest request = new PlanCategoryStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
        PlanCategoryStatCountResponse response = planScItemService.planCategoryStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatCategoryQueryRequest queryRequest = new StatCategoryQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statCategory(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnitCategory.salesPlanStatScItemList is empty");
                return;
            }
            List<String> businessUnitList = Lists.newArrayList();
            List<String> categoryList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                businessUnitList.add(salesPlanStatScItem.getBizId());
                if (!Objects.isNull(salesPlanStatScItem.getScItemCategoryId())) {
                    categoryList.add(salesPlanStatScItem.getScItemCategoryId());
                }
            }
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (!CollectionUtils.isEmpty(categoryList)) {
                //批量查询业务单元类目合同量，合同金额
                QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
                queryContractRequest.setType(ContractStatDimensionEnum.COMPANY_CATEGORY.getCode());
                queryContractRequest.setContractYear(year);
                queryContractRequest.setPlanMonth(month);
                queryContractRequest.setOrgBusinessUnitCodes(businessUnitList);
                queryContractRequest.setScItemCategoryIds(categoryList);
//        queryContractRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
                queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

                List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
                if (CollectionUtils.isNotEmpty(monthContractList)) {
                    collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgBusinessUnitCode(), m.getScItemCategoryId()), m -> m));
                }
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.CATEGORY.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemCategoryId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 类目维度
     * 销售组织类目汇总
     *
     * @param salesPlan
     */
    private void statOrganizationCategory(SalesPlanSDO salesPlan, String year, String month) {

        PlanCategoryStatCountRequest request = new PlanCategoryStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
        PlanCategoryStatCountResponse response = planScItemService.planCategoryStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatCategoryQueryRequest queryRequest = new StatCategoryQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statCategory(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statOrganizationCategory.salesPlanStatScItemList is empty");
                return;
            }
            //批量查询销售渠道类目合同量，合同金额
            List<String> organizationList = Lists.newArrayList();
            List<String> categoryList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                organizationList.add(salesPlanStatScItem.getBizId());
                if (!Objects.isNull(salesPlanStatScItem.getScItemCategoryId())) {
                    categoryList.add(salesPlanStatScItem.getScItemCategoryId());
                }
            }
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (!CollectionUtils.isEmpty(categoryList)) {
                //批量查询销售组织类目合同量，合同金额
                QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
                queryContractRequest.setType(ContractStatDimensionEnum.SALES_ORG_CATEGORY.getCode());
                queryContractRequest.setContractYear(year);
                queryContractRequest.setPlanMonth(month);
                queryContractRequest.setOrgSalesOrganizationCodes(organizationList);
                queryContractRequest.setScItemCategoryIds(categoryList);
                queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
                List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
                if (CollectionUtils.isNotEmpty(monthContractList)) {
                    collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesOrganizationCode(), m.getScItemCategoryId()), m -> m));
                }
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.CATEGORY.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemCategoryId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 类目维度
     * 销售渠道类目汇总
     *
     * @param salesPlan
     */
    private void statChannelCategory(SalesPlanSDO salesPlan, String year, String month) {

        PlanCategoryStatCountRequest request = new PlanCategoryStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
        PlanCategoryStatCountResponse response = planScItemService.planCategoryStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatCategoryQueryRequest queryRequest = new StatCategoryQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statCategory(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statChannelCategory.salesPlanStatScItemList is empty");
                return;
            }
            //批量查询销售渠道类目合同量，合同金额
            List<String> channelList = Lists.newArrayList();
            List<String> categoryList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                channelList.add(salesPlanStatScItem.getBizId());
                if (!Objects.isNull(salesPlanStatScItem.getScItemCategoryId())) {
                    categoryList.add(salesPlanStatScItem.getScItemCategoryId());
                }
            }
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (!CollectionUtils.isEmpty(categoryList)) {
                //批量查询业务单元类目合同量，合同金额
                QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
                queryContractRequest.setType(ContractStatDimensionEnum.SALES_CHANNEL_CATEGORY.getCode());
                queryContractRequest.setContractYear(year);
                queryContractRequest.setPlanMonth(month);
                queryContractRequest.setOrgSalesChannelCodes(channelList);
                queryContractRequest.setScItemCategoryIds(categoryList);
                queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
                List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
                if (CollectionUtils.isNotEmpty(monthContractList)) {
                    collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesChannelCode(), m.getScItemCategoryId()), m -> m));
                }
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.CATEGORY.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemCategoryId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 类目维度
     * 销售部门类目汇总
     *
     * @param salesPlan
     */
    private void statDepartmentCategory(SalesPlanSDO salesPlan, String year, String month) {

        PlanCategoryStatCountRequest request = new PlanCategoryStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
        PlanCategoryStatCountResponse response = planScItemService.planCategoryStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatCategoryQueryRequest queryRequest = new StatCategoryQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statCategory(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statDepartmentCategory.salesPlanStatScItemList is empty");
                return;
            }
            //批量查询销售部门类目合同量，合同金额
            List<String> departmentList = Lists.newArrayList();
            List<String> categoryList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                if (!Objects.isNull(salesPlanStatScItem.getBizId())) {
                    departmentList.add(salesPlanStatScItem.getBizId());
                }
                if (!Objects.isNull(salesPlanStatScItem.getScItemCategoryId())) {
                    categoryList.add(salesPlanStatScItem.getScItemCategoryId());
                }
            }
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();

            if (CollectionUtils.isEmpty(departmentList) || CollectionUtils.isEmpty(categoryList)) {
                QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
                queryContractRequest.setType(ContractStatDimensionEnum.DEPARTMENT_CATEGORY.getCode());
                queryContractRequest.setContractYear(year);
                queryContractRequest.setPlanMonth(month);
                queryContractRequest.setOrgSalesDepartmentCodes(departmentList);
                queryContractRequest.setScItemCategoryIds(categoryList);
                queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
                List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
                if (CollectionUtils.isNotEmpty(monthContractList)) {
                    collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesDepartmentCode(), m.getScItemCategoryId()), m -> m));
                }

            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.CATEGORY.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemCategoryId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 类目维度
     * 业务员类目汇总
     *
     * @param salesPlan
     */
    private void statEmployeeCategory(SalesPlanSDO salesPlan, String year, String month) {

        PlanCategoryStatCountRequest request = new PlanCategoryStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
        PlanCategoryStatCountResponse response = planScItemService.planCategoryStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatCategoryQueryRequest queryRequest = new StatCategoryQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statCategory(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statEmployeeCategory.salesPlanStatScItemList is empty");
                return;
            }
            List<String> salesManList = Lists.newArrayList();
            List<String> categoryList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                if (!Objects.isNull(salesPlanStatScItem.getBizId())) {
                    salesManList.add(salesPlanStatScItem.getBizId());
                }
                if (!Objects.isNull(salesPlanStatScItem.getScItemCategoryId())) {
                    categoryList.add(salesPlanStatScItem.getScItemCategoryId());
                }
            }
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (!CollectionUtils.isEmpty(salesManList) && !CollectionUtils.isEmpty(categoryList)) {
                //批量查询业务员类目合同量，合同金额
                QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
                queryContractRequest.setType(ContractStatDimensionEnum.EMPLOYEE_CATEGORY.getCode());
                queryContractRequest.setContractYear(year);
                queryContractRequest.setPlanMonth(month);
                queryContractRequest.setManageEmployeeIds(salesManList);
                queryContractRequest.setScItemCategoryIds(categoryList);
                queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
                List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);

                if (CollectionUtils.isNotEmpty(monthContractList)) {
                    collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getManageEmployeeId(), m.getScItemCategoryId()), m -> m));
                }
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.CATEGORY.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemCategoryId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }


    /**
     * 组织维度
     * 业务单元维度汇总
     *
     * @param salesPlan
     */
    private void statBusinessUnit(SalesPlanSDO salesPlan, String year, String month) {

        PlanOrganizationStatCountRequest request = new PlanOrganizationStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
        PlanOrganizationStatCountResponse response = planScItemService.planOrganizationStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatOrganizationQueryRequest queryRequest = new StatOrganizationQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statOrganization(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit.salesPlanStatScItemList is empty");
                return;
            }
            //批量查询销售组织合同量，合同金额
            List<String> businessUnitList = salesPlanStatScItemList.stream().map(SalesPlanStatScItemSDO::getBizId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(businessUnitList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit businessUnitList is empty");
                return;
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.COMPANY.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgBusinessUnitCodes(businessUnitList);
//        queryContractRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getOrgBusinessUnitCode, m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.ORGANIZATION.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(planStatScItem.getBizId());
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 组织维度
     * 销售组织维度汇总
     *
     * @param salesPlan
     */
    private void statOrganization(SalesPlanSDO salesPlan, String year, String month) {

        PlanOrganizationStatCountRequest request = new PlanOrganizationStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
        PlanOrganizationStatCountResponse response = planScItemService.planOrganizationStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatOrganizationQueryRequest queryRequest = new StatOrganizationQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statOrganization(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售组织合同量，合同金额
            List<String> organizationList = salesPlanStatScItemList.stream().map(SalesPlanStatScItemSDO::getBizId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(organizationList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit organizationList is empty");
                return;
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.SALES_ORGANIZATION.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesOrganizationCodes(organizationList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getOrgSalesOrganizationCode, m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.ORGANIZATION.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(planStatScItem.getBizId());
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 组织维度
     * 销售渠道维度汇总
     *
     * @param salesPlan
     */
    private void statChannel(SalesPlanSDO salesPlan, String year, String month) {

        PlanOrganizationStatCountRequest request = new PlanOrganizationStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
        PlanOrganizationStatCountResponse response = planScItemService.planOrganizationStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatOrganizationQueryRequest queryRequest = new StatOrganizationQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statOrganization(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售渠道合同量，合同金额
            List<String> channelList = salesPlanStatScItemList.stream().map(SalesPlanStatScItemSDO::getBizId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(channelList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit channelList is empty");
                return;
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.SALES_CHANNEL.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesChannelCodes(channelList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getOrgSalesChannelCode, m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.ORGANIZATION.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(planStatScItem.getBizId());
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 组织维度
     * 销售部门维度汇总
     *
     * @param salesPlan
     */
    private void statDepartment(SalesPlanSDO salesPlan, String year, String month) {

        PlanOrganizationStatCountRequest request = new PlanOrganizationStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
        PlanOrganizationStatCountResponse response = planScItemService.planOrganizationStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatOrganizationQueryRequest queryRequest = new StatOrganizationQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statOrganization(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售部门合同量，合同金额
            List<String> departmentList = salesPlanStatScItemList.stream().map(SalesPlanStatScItemSDO::getBizId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(departmentList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit departmentList is empty");
                return;
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.DEPARTMENT.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesDepartmentCodes(departmentList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getOrgSalesDepartmentCode, m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.ORGANIZATION.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(planStatScItem.getBizId());
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 组织维度
     * 业务员维度汇总
     *
     * @param salesPlan
     */
    private void statEmployee(SalesPlanSDO salesPlan, String year, String month) {

        PlanOrganizationStatCountRequest request = new PlanOrganizationStatCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        request.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
        request.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
        PlanOrganizationStatCountResponse response = planScItemService.planOrganizationStatCount(request);
        if (Objects.isNull(response)) {
            return;
        }
        Integer count = response.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatOrganizationQueryRequest queryRequest = new StatOrganizationQueryRequest();
            queryRequest.setPlanId(salesPlan.getId().toString());
            queryRequest.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
            queryRequest.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
            queryRequest.setPage(i);
            queryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanScItemStatRepository.statOrganization(queryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询业务员合同量，合同金额
            List<String> salesmanList = salesPlanStatScItemList.stream().map(SalesPlanStatScItemSDO::getBizId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(salesmanList)) {
                log.error("SalesPlanStatServiceImpl.statBusinessUnit salesmanList is empty");
                return;
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.EMPLOYEE.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setManageEmployeeIds(salesmanList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(MonthContractAndRollingCountResponse::getManageEmployeeId, m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.ORGANIZATION.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(planStatScItem.getBizId());
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 货品维度
     * 业务单元货品汇总
     *
     * @param salesPlan
     */
    private void statBusinessUnitScItem(SalesPlanSDO salesPlan, String year, String month) {

        PlanScItemStatByBusinessUnitCountRequest request = new PlanScItemStatByBusinessUnitCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        PlanScItemStatByBusinessUnitCountResponse planScItemStatByBusinessUnitCount = salesPlanDetailService.planScItemStatByBusinessUnitCount(request);
        if (Objects.isNull(planScItemStatByBusinessUnitCount)) {
            return;
        }
        Integer count = planScItemStatByBusinessUnitCount.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatScItemQueryRequest statQueryRequest = new StatScItemQueryRequest();
            statQueryRequest.setPlanId(salesPlan.getId().toString());
            statQueryRequest.setOrgBusinessUnit(true);
            statQueryRequest.setPage(i);
            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanLineRepository.queryStatPlanScItemList(statQueryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询业务单元货品合同量，合同金额
            List<String> businessUnitList = Lists.newArrayList();
            List<String> scItemIdList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                if (!Objects.isNull(salesPlanStatScItem.getBizId())) {
                    businessUnitList.add(salesPlanStatScItem.getBizId());
                }
                if (Objects.isNull(salesPlanStatScItem.getScItemId())) {
                    scItemIdList.add(salesPlanStatScItem.getScItemId());
                }
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.COMPANY_SC_ITEM.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgBusinessUnitCodes(businessUnitList);
            queryContractRequest.setScItemIds(scItemIdList);
//        queryContractRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgBusinessUnitCode(), m.getScItemId()), m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.BUSINESS_UNIT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 货品维度
     * 销售组织货品汇总
     *
     * @param salesPlan
     */
    private void statOrganizationScItem(SalesPlanSDO salesPlan, String year, String month) {

        PlanScItemStatBySalesOrganizationCountRequest request = new PlanScItemStatBySalesOrganizationCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        PlanScItemStatBySalesOrganizationCountResponse planScItemStatBySalesOrganizationCount = salesPlanDetailService.planScItemStatBySalesOrganizationCount(request);
        if (Objects.isNull(planScItemStatBySalesOrganizationCount)) {
            return;
        }
        Integer count = planScItemStatBySalesOrganizationCount.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatScItemQueryRequest statQueryRequest = new StatScItemQueryRequest();
            statQueryRequest.setPlanId(salesPlan.getId().toString());
            statQueryRequest.setOrgSalesOrganization(true);
            statQueryRequest.setPage(i);
            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanLineRepository.queryStatPlanScItemList(statQueryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售组织货品合同量，合同金额
            List<String> organizationList = Lists.newArrayList();
            List<String> scItemIdList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                organizationList.add(salesPlanStatScItem.getBizId());
                scItemIdList.add(salesPlanStatScItem.getScItemId());
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.SALES_ORG_SC_ITEM.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesOrganizationCodes(organizationList);
            queryContractRequest.setScItemIds(scItemIdList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesOrganizationCode(), m.getScItemId()), m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_ORGANIZATION.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 货品维度
     * 销售渠道货品汇总
     *
     * @param salesPlan
     */
    private void statChannelScItem(SalesPlanSDO salesPlan, String year, String month) {

        PlanScItemStatBySalesChannelCountRequest request = new PlanScItemStatBySalesChannelCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        PlanScItemStatBySalesChannelCountResponse planScItemStatBySalesChannelCount = salesPlanDetailService.planScItemStatBySalesChannelCount(request);
        if (Objects.isNull(planScItemStatBySalesChannelCount)) {
            return;
        }
        Integer count = planScItemStatBySalesChannelCount.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatScItemQueryRequest statQueryRequest = new StatScItemQueryRequest();
            statQueryRequest.setPlanId(salesPlan.getId().toString());
            statQueryRequest.setOrgSalesChannel(true);
            statQueryRequest.setPage(i);
            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanLineRepository.queryStatPlanScItemList(statQueryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售渠道货品合同量，合同金额
            List<String> channelList = Lists.newArrayList();
            List<String> scItemIdList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                channelList.add(salesPlanStatScItem.getBizId());
                scItemIdList.add(salesPlanStatScItem.getScItemId());
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.SALES_CHANNEL_SC_ITEM.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesChannelCodes(channelList);
            queryContractRequest.setScItemIds(scItemIdList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesChannelCode(), m.getScItemId()), m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 货品维度
     * 销售部门货品汇总
     *
     * @param salesPlan
     */
    private void statDepartmentScItem(SalesPlanSDO salesPlan, String year, String month) {
        PlanScItemStatBySalesDepartmentCountRequest request = new PlanScItemStatBySalesDepartmentCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        PlanScItemStatBySalesDepartmentCountResponse planScItemStatBySalesDepartmentCount = salesPlanDetailService.planScItemStatBySalesDepartmentCount(request);
        if (Objects.isNull(planScItemStatBySalesDepartmentCount)) {
            return;
        }
        Integer count = planScItemStatBySalesDepartmentCount.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatScItemQueryRequest statQueryRequest = new StatScItemQueryRequest();
            statQueryRequest.setPlanId(salesPlan.getId().toString());
            statQueryRequest.setOrgSalesDepartment(true);
            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            statQueryRequest.setPage(i);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanLineRepository.queryStatPlanScItemList(statQueryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询销售部门货品合同量，合同金额
            List<String> departmentList = Lists.newArrayList();
            List<String> scItemIdList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                departmentList.add(salesPlanStatScItem.getBizId());
                scItemIdList.add(salesPlanStatScItem.getScItemId());
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.DEPARTMENT_SC_ITEM.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setOrgSalesDepartmentCodes(departmentList);
            queryContractRequest.setScItemIds(scItemIdList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getOrgSalesDepartmentCode(), m.getScItemId()), m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 货品维度
     * 业务员货品汇总
     *
     * @param salesPlan
     */
    private void statEmployeeScItem(SalesPlanSDO salesPlan, String year, String month) {

        PlanScItemStatByManageEmployeeCountRequest request = new PlanScItemStatByManageEmployeeCountRequest();
        request.setPlanId(salesPlan.getId().toString());
        PlanScItemStatByManageEmployeeCountResponse planScItemStatByManageEmployeeCount = salesPlanDetailService.planScItemStatByManageEmployeeCount(request);
        if (Objects.isNull(planScItemStatByManageEmployeeCount)) {
            return;
        }
        Integer count = planScItemStatByManageEmployeeCount.getCount();
        if (count == null || count <= 0) {
            log.warn("SalesPlanStatServiceImpl.planCustomerCollect planCustomerAddress nothingness");
            return;
        }
        int totalPage = (count + CUSTOMER_ADDRESS_PAGE_SIZE - 1) / CUSTOMER_ADDRESS_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            StatScItemQueryRequest statQueryRequest = new StatScItemQueryRequest();
            statQueryRequest.setPlanId(salesPlan.getId().toString());
            statQueryRequest.setManageEmployee(true);
            statQueryRequest.setPage(i);
            statQueryRequest.setSize(CUSTOMER_ADDRESS_PAGE_SIZE);
            List<SalesPlanStatScItemSDO> salesPlanStatScItemList = salesPlanLineRepository.queryStatPlanScItemList(statQueryRequest);
            if (CollectionUtils.isEmpty(salesPlanStatScItemList)) {
                return;
            }
            //批量查询业务员货品合同量，合同金额
            Set<String> salesManList = Sets.newHashSet();
            List<String> scItemIdList = Lists.newArrayList();
            for (SalesPlanStatScItemSDO salesPlanStatScItem : salesPlanStatScItemList) {
                salesManList.add(salesPlanStatScItem.getBizId());
                scItemIdList.add(salesPlanStatScItem.getScItemId());
            }
            QueryContractByCustomerDimensionRequest queryContractRequest = new QueryContractByCustomerDimensionRequest();
            queryContractRequest.setType(ContractStatDimensionEnum.EMPLOYEE_SC_ITEM.getCode());
            queryContractRequest.setContractYear(year);
            queryContractRequest.setPlanMonth(month);
            queryContractRequest.setManageEmployeeIds(Lists.newArrayList(salesManList));
            queryContractRequest.setScItemIds(scItemIdList);
            queryContractRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());

            List<MonthContractAndRollingCountResponse> monthContractList = contractRepository.queryQuantityListByAddressAndScItem(queryContractRequest);
            Map<String, MonthContractAndRollingCountResponse> collect = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(monthContractList)) {
                collect = monthContractList.stream().collect(Collectors.toMap(m -> SalesPlanCommonService.getCombinationKey(m.getManageEmployeeId(), m.getScItemId()), m -> m));
            }
            for (SalesPlanStatScItemSDO planStatScItem : salesPlanStatScItemList) {
                planStatScItem.setPoolType(StatPoolTypeEnum.SC_ITEM.getPoolType());
                planStatScItem.setBizType(SalesStatBizTypeEnum.SALESMAN.getBizType());
                //需要查合同量补充
                MonthContractAndRollingCountResponse monthContract = collect.get(SalesPlanCommonService.getCombinationKey(planStatScItem.getBizId(), planStatScItem.getScItemId()));
                setStatContractInfo(planStatScItem, monthContract);
                calculateSatisfaction(salesPlan.getStatus(), planStatScItem);
            }
            salesPlanScItemStatRepository.batchCreatePlanScItem(salesPlanStatScItemList);
        }
    }

    /**
     * 设置汇总记录合同信息
     *
     * @param statSDO
     * @param monthContract
     */
    private void setStatContractInfo(SalesPlanStatSDO statSDO, MonthContractAndRollingCountResponse monthContract) {
        statSDO.setMonthContractCount(Objects.isNull(monthContract) ? 0 : monthContract.getMonthContractCount());
        statSDO.setBeforeMonthContractMoney(Objects.isNull(monthContract) ? 0L : monthContract.getBeforeMonthContractMoney());
        statSDO.setMonthContractMoney(Objects.isNull(monthContract) ? 0L : monthContract.getMonthContractMoney());
    }

    private void calculateSatisfaction(Integer status, SalesPlanStatSDO salesPlanStat) {
        SalesPlanStatusEnum match = SalesPlanStatusEnum.match(status);
        salesPlanStat.setStatus(status);
        switch (match) {
            case TO_BE_LOCKED:
            case TO_BE_SYNC:
            case TO_BE_REPLIED:
            case TO_BE_PUBLISHED:
                salesPlanStat.calculatePlanSatisfaction();
                break;
            case PUBLISHED:
                salesPlanStat.calculateTaskSatisfaction();
                break;
            case ADJUST:
                salesPlanStat.calculateAdjustSatisfaction();
                break;
            default:
                break;
        }
    }

    @Override
    public Result<Boolean> consumePlanCollect(String message) {
        if (StringUtils.isBlank(message)) {
            return Result.success(true);
        }
        Result<Boolean> booleanResult = null;
        try {
            booleanResult = planCollect(message);
        } catch (Exception e) {
            log.error("SalesPlanStatServiceImpl#consumePlanCollect_fail " + "触发月度计划汇总消费异常", e);
        }
        return booleanResult == null ? Result.success(true) : booleanResult;
    }

    public static void main(String[] args) {
        System.out.println("开始");
        long startNanoTime = System.nanoTime();
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
            int t = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("f1=" + t);
        });

        CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
            int t = new Random().nextInt(3);
            try {
                TimeUnit.SECONDS.sleep(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("f2=" + t);
        });
        CompletableFuture<Void> voidCompletableFuture = f1.runAfterBoth(f2, new Runnable() {
            @Override
            public void run() {
                long escapedMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
                System.out.println("上面两个任务都执行完成了。时间：" + escapedMillis);
            }
        });
        voidCompletableFuture.join();
        System.out.println("结束");
    }

    public static void test() {
        System.out.println("开始");

        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int t = new Random().nextInt(3);
                try {
                    TimeUnit.SECONDS.sleep(t);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("f1=" + t);
                return t;
            }
        });

        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int t = new Random().nextInt(3);
                try {
                    TimeUnit.SECONDS.sleep(t);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("f2=" + t);
                return t;
            }
        });
        CompletableFuture<Void> voidCompletableFuture = f1.runAfterBoth(f2, new Runnable() {
            @Override
            public void run() {
                System.out.println("上面两个任务都执行完成了。");
            }
        });
        voidCompletableFuture.join();
        System.out.println("结束");
    }
}
